import json
from typing import List, Union, Optional, Dict, Tuple

from tencentcloud.common import credential
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
from tencentcloud.sms.v20210111 import sms_client, models

from .config import CONF


def send_sms(
    PhoneNumberSet: Union[str, List[str]],
    TemplateParamSet: List[str],
    SmsSdkAppId: Optional[str] = None,
    SignName: Optional[str] = None,
    TemplateId: Optional[str] = None,
    secretId: Optional[str] = None,
    secretKey: Optional[str] = None,
    defaultConf: Optional[Dict[str, str]] = CONF['tencentcloud_sms']['verification_code']
) -> Tuple[int, str]:
    """
    发送模板短信

    Args:
        PhoneNumberSet (Union[str, List[str]]): 手机号(列表)
        TemplateParamSet (List[str]): 模板参数列表
        SmsSdkAppId (Optional[str], optional): 应用ID. Defaults to None.
        SignName (Optional[str], optional): 签名. Defaults to None.
        TemplateId (Optional[str], optional): 模板ID. Defaults to None.
        secretId (Optional[str], optional): SDK secretId. Defaults to None.
        secretKey (Optional[str], optional): SDK secretKey. Defaults to None.
        defaultConf (Optional[Dict[str, str]], optional): 默认配置, 配置项为None时会从该字典中获取. Defaults to CONF['tencentcloud_sms']['verification_code'].

    Returns:
        Tuple[int, str]: err_code, err_info
    """

    if not isinstance(PhoneNumberSet, list):
        PhoneNumberSet = [PhoneNumberSet]
    phone_number_set = []
    for num in PhoneNumberSet:
        if num[0] != "+":
            phone_number_set.append("+86" + num)

    if secretId is None:
        secretId = defaultConf['secretId']
    if secretKey is None:
        secretKey = defaultConf['secretKey']
    if SmsSdkAppId is None:
        SmsSdkAppId = defaultConf['SmsSdkAppId']
    if SignName is None:
        SignName = defaultConf['SignName']
    if TemplateId is None:
        TemplateId = defaultConf['TemplateId']

    err_code = 0
    err_info = ''
    try:
        cred = credential.Credential(secretId, secretKey)
        httpProfile = HttpProfile()
        httpProfile.endpoint = "sms.tencentcloudapi.com"

        clientProfile = ClientProfile()
        clientProfile.httpProfile = httpProfile
        client = sms_client.SmsClient(cred, "ap-nanjing", clientProfile)

        req = models.SendSmsRequest()
        params = {
            "PhoneNumberSet": phone_number_set,
            "SmsSdkAppId": SmsSdkAppId,
            "SignName": SignName,
            "TemplateId": TemplateId,
            "TemplateParamSet": TemplateParamSet
        }
        req.from_json_string(json.dumps(params))

        resp = client.SendSms(req)
        js = json.loads(resp.to_json_string())
        # print(json.dumps(js, indent=2, ensure_ascii=False))
        """
        {
            "Response": {  # 实际没有"Response"这一层
                "SendStatusSet": [
                    {
                        "SerialNo": "5000:1045710669157053657849499619",
                        "PhoneNumber": "+8618511122233",
                        "Fee": 1,
                        "SessionContext": "test",
                        "Code": "Ok",
                        "Message": "send success",
                        "IsoCode": "CN"
                    },
                    {
                        "SerialNo": "5000:1045710669157053657849499718",
                        "PhoneNumber": "+8618511122266",
                        "Fee": 1,
                        "SessionContext": "test",
                        "Code": "Ok",
                        "Message": "send success",
                        "IsoCode": "CN"
                    }
                ],
                "RequestId": "a0aabda6-cf91-4f3e-a81f-9198114a2279"
            }
        }
        """
        for SendStatus in js["SendStatusSet"]:
            if SendStatus["Code"].upper() != "OK":
                err_code = 1
                err_info = "{}: {}".format(
                    SendStatus["PhoneNumber"], SendStatus["Message"]
                )
                break

    except TencentCloudSDKException as err:
        err_code = 1
        err_info = "[TencentCloudSDKException] " + str(err)
    return err_code, err_info
